Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

178
Visualizações
When updating className css transition "one step behind"

I have a form that "slides in" the different steps as cards, e.g. when moving from step 1 to step 2 the card appears from the right, and when moving back from e.g. step 3 to step 2 the card slides in from the left.

My problem is that the direction is "one step behind", it takes two clicks in one direction for the transition to catch up.

When the prev/next buttons are clicked handleActive() is called:

const handleActive = (num, text) => {
   setDirection(text)
   setActive(num)
}

An example of a card div

<div className={active === 2 ? 'card-active' : 'card-' + direction}>
<h4>Step {active}</h4>
<input className='input' type="text" name="name" id="name" placeholder='Name' />
<input className='input' type="text" name="address" id="address" placeholder='Address' />
<input className='input' type="text" name="phone" id="phone" placeholder='Phone' />
<button className='btn' type="button" onClick={() => handleActive(-1, 'from-left')}>PREV</button>
<button className='btn' type="button" onClick={() => handleActive(1, 'from-right')}>NEXT</button>
</div>

CSS:

.card-from-right {
   ...
  left: 35%;
  transition: left 800ms 0ms ease-out, height 0ms 800ms, opacity 400ms 0ms ease-in;

}

.card-from-left {
   ...
  left: 25%;
  transition: left 800ms 0ms ease-out, height 0ms 800ms, opacity 400ms 0ms ease-in;
}

.card-active {
   ...
  left: 30%;
}

I have tried async/await in the handleActive() function and useEffect, but the only thing that works is setTimeout (but that's too hacky)

const handleActive = async (num, text) => {
await setDirection(text)
await setActive(num)
}
const handleActive = async (num, text) => {
await setDirection(text)
  setTimeout(() => {
    setActive(num)
  }, 600);
}

How could I pause (and modify the DOM?) to update the classNames before running setActive()? Console.log and the source code show the correct classNames, but somehow not in time before setActive()...

about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

This is a rough idea of using useEffect. You could also use num as a dependency if you need. Or you could use functions. My main point would be to put most if not all of the conditional logic inside of useEffect. (or at least be abstracted from useEffect)

useEffect(() => {
  if (direction === "to-left") {
    setActive(-1)
  } else {
   setActive(1)
  }
}, [direction]);
about 4 years ago · Juan Pablo Isaza Relatório

0

I was able to solve the problem with a "placeholder variable" - activeSetter (the problem with the earlier useEffect solution was that it was not triggered if the direction didn't change). Now everything happens in the right order:

  • the right className is set on non-active cards
  • the activeSetter holds the number of the next active card
  • and changes in activeSetter triggers useEffect that sets the new active card
const [activeSetter, setActiveSetter] = useState(1)

  useEffect(() => {
    setActive(activeSetter)
  }, [setActive, activeSetter])
  

  const handleActive = (num, text) => {
    setDirection(text)
    setActiveSetter(num)
  }
about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda